/**
 * Created by XianTao on 16-11-13
 * <p/>
 * Copyright (c) 2016
 * Apache License
 * Version 2.0, January 2004
 * http://www.apache.org/licenses/
 */
package org.lego.biz.wechat.lechuan.mobile.api.restful;

import com.google.code.kaptcha.Constants;
import org.lego.biz.wechat.lechuan.base.entity.PushNews;
import org.lego.biz.wechat.lechuan.base.entity.UserPrize;
import org.lego.biz.wechat.lechuan.base.service.PushNewsService;
import org.lego.biz.wechat.lechuan.base.service.UserPrizeService;
import org.lego.biz.wechat.lechuan.mobile.api.vo.CheckHasPrizeVo;
import org.lego.jpa.base.util.DynamicSpecifications;
import org.lego.jpa.base.vo.ResultVo;
import org.lego.util.DateTimeUtil;
import org.lego.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.security.InvalidParameterException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/mobile/prize", method = RequestMethod.POST)
public class PrizeRestful {
    @Autowired
    private PushNewsService pushNewsService;
    @Autowired
    private UserPrizeService userPrizeService;

    /**
     * 添加手机号对应礼品，并返回领取礼品的关键字
     * （领取礼品分为两步：第一步提交手机号码得到礼品关键字，第二步在公众号里输入关键字领取礼品。此方法为第一步）
     *
     * @param userPrize
     * @param request
     * @return
     */
    @RequestMapping(value = "/add")
    @Transactional
    public synchronized ResultVo<UserPrize> addPrize(@RequestBody UserPrize userPrize, HttpServletRequest request) {
        if (ObjectUtils.isEmpty(userPrize.getPushNews())
                || ObjectUtils.isEmpty(userPrize.getPushNews().getId())
                || ObjectUtils.isEmpty(userPrize.getTelephone())
                || ObjectUtils.isEmpty(userPrize.getCaptcha())) {
            throw new InvalidParameterException("wrong param");
        }
        if (!StringUtil.isTelephone(userPrize.getTelephone())) {
            return new ResultVo<UserPrize>(ResultVo.STATUS_SUCCESS, "手机号码输入有误", null);
        }
        if (!userPrize.getCaptcha().equals(request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY))) {
            return new ResultVo<UserPrize>(ResultVo.STATUS_SUCCESS, "验证码输入有误", null);
        }
        PushNews currentPushNews = pushNewsService.findOne(userPrize.getPushNews().getId());
        if (ObjectUtils.isEmpty(currentPushNews)) {
            throw new InvalidParameterException("wrong param");
        }
        userPrize.setPushNews(currentPushNews);

        //获取礼品规则验证：同一个图文，每个手机号码仅可领取一次
        Map<String, Object> searchParams = new HashMap<String, Object>();
        searchParams.put("EQ_pushNews.id", userPrize.getPushNews().getId());
        searchParams.put("EQ_telephone", userPrize.getTelephone());
        List<UserPrize> userPrizeListByTelephone = userPrizeService.findAll(DynamicSpecifications.buildSpecification(searchParams, UserPrize.class));
        if (!ObjectUtils.isEmpty(userPrizeListByTelephone)) {
            return new ResultVo<UserPrize>(ResultVo.STATUS_SUCCESS, "亲！您的手机号码已经领过礼品，好东西不能独享，赶快告诉亲朋好友吧！", null);
        }
        // 确认还有礼品
        if (currentPushNews.getPrizeTotal() <= userPrizeService.count(currentPushNews.getId())) {
            return new ResultVo<UserPrize>(ResultVo.STATUS_SUCCESS, "亲！您的手有点慢哟，礼品已全部发送完，下次请及时输入礼品代码。", null);
        }

        // 生成随机礼品关键字
        userPrize.setPrizeCode(StringUtil.getRandomStr(6));

        userPrize.setCreateTime(DateTimeUtil.getCurrentTimeSeconds());
        userPrizeService.saveAndFlush(userPrize);
        return new ResultVo<UserPrize>(userPrize);
    }

    /**
     * 获取已领礼品列表
     *
     * @param openId
     * @param pageNum
     * @return
     */
    @RequestMapping(value = "/get/{openId}/{pageNum}")
    public ResultVo<Page<UserPrize>> getUserPrizeListByOpenId(@PathVariable("openId") String openId, @PathVariable("pageNum") int pageNum) {
        if (ObjectUtils.isEmpty(openId)) {
            throw new InvalidParameterException("wrong param");
        }

        Map<String, Object> searchParams = new HashMap<String, Object>();
        searchParams.put("EQ_openId", openId);
        Page<UserPrize> userPrizePage = userPrizeService.findAll(
                DynamicSpecifications.buildSpecification(searchParams, UserPrize.class),
                new PageRequest(pageNum, 10, Sort.Direction.DESC, "createTime"));
        return new ResultVo<Page<UserPrize>>(userPrizePage);
    }

    /**
     * 获取未领礼品列表
     *
     * @param telephone
     * @return
     */
    @RequestMapping(value = "/getUnFetch/{telephone}/{pageNum}")
    public ResultVo<Page<UserPrize>> getUserUnFetchPrizeListByTelephone(@PathVariable("telephone") String telephone, @PathVariable("pageNum") int pageNum) {
        Map<String, Object> searchParams = new HashMap<String, Object>();
        searchParams.put("EQ_telephone", telephone);
        searchParams.put("ISNULL_openId", "null");
        Page<UserPrize> userPrizePage = userPrizeService.findAll(
                DynamicSpecifications.buildSpecification(searchParams, UserPrize.class),
                new PageRequest(pageNum, 10, Sort.Direction.DESC, "createTime"));
        return new ResultVo<Page<UserPrize>>(userPrizePage);
    }

    /**
     * 检查此图文是否还有礼品
     *
     * @param newsId 图文id
     * @return
     */
    @RequestMapping(value = "/check/{newsId}")
    public ResultVo<CheckHasPrizeVo> checkHasPrize(@PathVariable("newsId") String newsId) {
        CheckHasPrizeVo checkHasPrizeVo = new CheckHasPrizeVo();

        PushNews currentPushNews = pushNewsService.findOne(newsId);
        if (ObjectUtils.isEmpty(currentPushNews)) {
            throw new InvalidParameterException("wrong param");
        }
        if (currentPushNews.getPrizeTotal() <= userPrizeService.count(currentPushNews.getId())) {
            checkHasPrizeVo.setResultMessage("礼品已被领完，下次早点来哟");
            checkHasPrizeVo.setOriginalNewsUrl(currentPushNews.getNewsUrl());
        }
        return new ResultVo<CheckHasPrizeVo>(checkHasPrizeVo);
    }
}
